package component

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisStatus"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Number"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/periodTask"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEnv"
	"gitee.com/fierce_wolf/go-fox-edge-kernel-common/gatewayRouter"
	"strings"
	"time"
)

type gateWayRouteUpdateTask struct {
}

func (e *gateWayRouteUpdateTask) TaskType() periodTask.TaskType {
	return periodTask.TaskShare
}

func (e *gateWayRouteUpdateTask) SchedulePeriod() int64 {
	return 10
}

func (e *gateWayRouteUpdateTask) Execute() {
	// 获得gateway的动态路由
	routes, err := e.getRoutes()
	if err != nil {
		return
	}

	// 通过PS命令获得进程列表
	processList := e.getProcess(10 * 60 * 1000)

	// 注册路由
	e.registerRout(routes, processList)

	return
}

func (e *gateWayRouteUpdateTask) getProcess(timeout int64) []map[string]interface{} {
	dataList := commRedisStatus.GetDataList(-1)

	resultList := make([]map[string]interface{}, 0)
	for _, data := range dataList {
		serviceName := data["serviceName"]
		serviceType := data["serviceType"]
		activeTime := data["activeTime"]
		appPort := data["appPort"]

		// 检查参数信息
		if Method.HasEmpty(serviceName, serviceType) {
			continue
		}

		if time.Now().UnixMilli()-Number.MakeInt64(activeTime) > timeout {
			continue
		}

		result := make(map[string]interface{})
		result["appName"] = serviceName
		result["appType"] = serviceType
		result["activeTime"] = activeTime
		result["appPort"] = appPort

		resultList = append(resultList, result)
	}

	return resultList
}

func (e *gateWayRouteUpdateTask) getRoutes() (map[string]string, error) {
	routers, err := gatewayRouter.GetRouterConfig()
	if err != nil {
		return nil, err
	}

	result := make(map[string]string)
	for _, router := range routers {
		if router.Id == "" {
			continue
		}

		if !strings.HasPrefix(router.Uri, "http://localhost:") {
			continue
		}

		result[router.Id] = router.Uri
	}

	return result, nil
}

func (e *gateWayRouteUpdateTask) registerRout(routes map[string]string, processList []map[string]interface{}) {
	for _, data := range processList {
		appName := data["appName"]
		appType := data["appType"]
		appPort := data["appPort"]

		// 检查参数信息
		if Method.HasNull(appName, appType, appPort) {
			continue
		}
		if Method.HasEmpty(appName, appType) {
			continue
		}

		// 检查：是否为gateway进程，它本身管路由，不需要配置路由
		if edgeEnv.Name.IsGateWay(appType.(string), appName.(string)) {
			continue
		}

		// 重置appName：将manager-native 改名为manager-service
		appName = edgeEnv.Name.GetAppName(appType.(string), appName.(string))

		// 检查：该进程是否在gateway这边进行了注册动态路由
		id := GateWayRouteService.BuildId(appName.(string), appType.(string))

		_, ok := routes[id]
		if ok {
			// 场景1：路由内容一致，不需要处理
			uri := GateWayRouteService.BuildUri(appName.(string), appType.(string), Number.MakeInt(appPort))
			if uri == routes[id] {
				continue
			} else {
				// 场景2：路由内容不一致，就重新刷新
				GateWayRouteService.UpdateRouter(appName.(string), appType.(string), Number.MakeInt(appPort))
				continue
			}
		} else {
			// 路由不存在，向网关注册动态路由：这样，启动的服务才能够从网关进行转发
			GateWayRouteService.RegisterRouter(appName.(string), appType.(string), Number.MakeInt(appPort))
			continue
		}
	}
}
